package org.gd.hellojavacore.patterns.lazyinitialization;

import org.gd.hellojavacore.patterns.CreationalPattern;

/**
 <pre>
 Отложенная (ленивая) инициализация (англ. Lazy initialization). Приём в программировании,
 когда некоторая ресурсоёмкая операция (создание объекта, вычисление значения) выполняется непосредственно
 перед тем, как будет использован её результат. Таким образом, инициализация выполняется «по требованию»,
 а не заблаговременно. Аналогичная идея находит применение в самых разных областях: например,
 компиляция «на лету» и логистическая концепция «Точно в срок».

 Частный случай ленивой инициализации — создание объекта в момент обращения к нему — является одним
 из порождающих шаблонов проектирования. Как правило, он используется в сочетании с такими шаблонами
 как Фабричный метод, Одиночка и Заместитель

 ----------------------------------------------------------------------------------------------

 Достоинства

 Инициализация выполняется только в тех случаях, когда она действительно необходима;
 ускоряется начальная инициализация

 ----------------------------------------------------------------------------------------------

 Недостатки

 Невозможно явным образом задать порядок инициализации объектов;
 возникает задержка при первом обращении к объекту

 </pre>
 */
public class LazyInitialization implements CreationalPattern {

    private static long totalMemory;
    // Этот флаг определяет, было ли выполнено вычисление
    private static boolean isCalc = false;

    private static long getTotalMemory() {
        // Определяем значение totalMemory только при первом вызове
        if (!isCalc) {
            totalMemory = Runtime.getRuntime().totalMemory() / 1024;
            isCalc = true;
        }
        return totalMemory;
    }

    public static void main(String...args) {

        // Здесь значение будет вычислено
        System.out.println("Total amount of memory: " + getTotalMemory() + " KB");

        // Здесь будет использовано значение, сохранённое в переменной
        if (getTotalMemory() > 1024) {
            System.out.println(SomeObject.getObject());
        }
    }
}

